//
// Created by zlxx on 2022/10/21.
//

#ifndef MINIDB_COMPOSITETUPLE_H
#define MINIDB_COMPOSITETUPLE_H
#include <vector>
#include <string>
#include "expression.h"
#include "common/log/log.h"
#include "tuple_cell.h"
#include "tuple.h"
#include "TupleValue.h"
/**
 * tuple集合,多表查询需要连接起来
 * 比如 表1 tuple1和表二 tuple2 连接就是往tuples加一个
 * 看到这有个现成的类就用它实现吧。。。
 */

class Field;
class CompositeTuple {
public:
  CompositeTuple()
  {}

  CompositeTuple(const CompositeTuple &other) : tuples_(other.tuples_)
  {}

  int cell_num()
  {
    int sum = 0;
    for (const auto& tp_value : tuples_) {
      sum += tp_value.cell_num();
    }
    return sum;
  }

  RC cell_at(int speces_index, TupleCell &cell)
  {
    if (speces_index < 0 || speces_index >= cell_num()) {
      LOG_WARN("invalid argument. speces_index=%d", speces_index);
      return RC::INVALID_ARGUMENT;
    }
    int tp_index = -1;
    int tp_entry_index = -1;
    find_index_in_tuples(speces_index, tp_index, tp_entry_index);
    tuples_[tp_index].cell_at(tp_entry_index, cell);
    return RC::SUCCESS;
  }

  RC find_cell(const Field &field, TupleCell &cell) const
  {
    for (const auto& tp_value : tuples_) {
      if (RC::SUCCESS == tp_value.find_cell(field, cell)) {
        return RC::SUCCESS;
      }
    }
    return RC::NOTFOUND;
  }

  RC add_row_tuple(TupleValue &tuple_value)
  {
    tuples_.push_back(tuple_value);
    return RC::SUCCESS;
  }

  RC remove_tail_tuple()
  {
    tuples_.pop_back();
    return RC::SUCCESS;
  }

  //! 找到tuple下标和index在这个tuple内的下标
  void find_index_in_tuples(int index, int &ret_tp_index, int &ret_entry_in_tp_index)
  {
    int tp_index = 0;
    for (const TupleValue &t : tuples_) {
      auto size = t.cell_num();
      if ((index - size) >= 0) {
        index -= size;
      } else {
        break;
      }
      tp_index++;
    }
    ret_tp_index = tp_index;
    ret_entry_in_tp_index = index;
  }
  std::vector<TupleValue> tuples() const {
    return tuples_;
  }


private:
  /**
   * tables ,tuples 1:1完全对照
   */
  std::vector<TupleValue> tuples_{};
};

#endif  // MINIDB_COMPOSITETUPLE_H
